package com.ruan.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruan.common.Code;
import com.ruan.common.Result;
import com.ruan.mapper.*;
import com.ruan.pojo.*;
import com.ruan.pojoExt.FileEntityExt;
import com.ruan.service.EmployeeService;
import com.ruan.service.FileService;
import com.ruan.service.ProjectService;
import com.ruan.utils.AliOSSUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

@Slf4j
@RestController
@RequestMapping("/file")
public class FileController {

    @Autowired
    private FileMapper fileMapper;

    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private ParticipantMapper participantMapper;

    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Value("${kejiu.path}")
    private String basePath;
    /**
     * 文件软删除
     */
    @GetMapping("/deleteSoft/{id}")
    @Transactional
    public Result deleteSoftFile(@PathVariable Integer id) {
        FileEntity fileEntity = fileMapper.selectById(id);
        if (fileEntity != null) {
            fileEntity.setIsDelete(FileEntity.IsDelete.deleted);
            fileMapper.updateById(fileEntity);
            return new Result(Code.DELETE_OK, "文件删除成功！");
        }
        return new Result(Code.DELETE_ERR, "文件删除失败：找不到文件记录！");
    }
    /**
     * 文件硬删除
     */
    @GetMapping("/deleteHard/{id}")
    @Transactional
    public Result deleteHardFile(@PathVariable Integer id) {
        // 查找文件记录
        FileEntity fileEntity = fileMapper.selectById(id);
        if (fileEntity != null) {
            // 获取文件路径
            String filePath = basePath + fileEntity.getFileName();
            File file = new File(filePath);

            // 删除文件 && file.delete()
            if (file.exists() && file.isFile()) {
                file.delete();
                // 从数据库中删除文件记录
                fileMapper.deleteById(id);
                return new Result(Code.DELETE_OK, "文件删除成功！");
            } else {
                fileMapper.deleteById(id);
                return new Result(Code.DELETE_ERR, "文件删除失败，文件不存在！");
            }
        }
        return new Result(Code.DELETE_ERR, "文件删除失败：找不到文件记录！");
    }

    /**
     * 所有文件硬删除
     */
    @GetMapping("/deleteHardAll/{id}")
    @Transactional
    public Result deleteHardAll(@PathVariable Integer id) {
        Employee employee = employeeMapper.selectById(id);
        if(employee == null || !employee.getStatus().equals("正式")){
            return new Result(Code.DELETE_ERR, "没有删除权限");
        }
        // 查找文件记录
        //根据员工id查出所有与项目的participant表里的有自己参与的projectId(需要去重)
        LambdaQueryWrapper<Participant> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(Participant::getEmployeeId, id);
        List<Participant> participantList = participantMapper.selectList(queryWrapper);
        if(participantList.size() == 0){
            return new Result(Code.DELETE_ERR, "文件删除失败，你没有参与任何项目！");
        }
        List<Long> projectIdList =
                participantList.stream().map(Participant::getProjectId).distinct().collect(Collectors.toList());

        int count = 0;
        for (Long projectId : projectIdList) {
            LambdaQueryWrapper<FileEntity> queryWrapper1 = new LambdaQueryWrapper<>();
            queryWrapper1.eq(FileEntity::getProjectId, projectId);
            queryWrapper1.eq(FileEntity::getIsDelete, FileEntity.IsDelete.deleted);
            List<FileEntity> fileEntityList = fileMapper.selectList(queryWrapper1);
            for (FileEntity fileEntity : fileEntityList) {
                String filePath = basePath + fileEntity.getFileName();
                File file = new File(filePath);
                if (file.exists() && file.isFile()) {
                    file.delete();
                    count = count + 1;
                }
                // 从数据库中删除文件记录
                fileMapper.deleteById(fileEntity.getId());
            }
        }
        if(count == 0){
            return new Result(Code.DELETE_ERR, "回收站为空！");
        }
        return new Result(Code.DELETE_OK, "回收站已清空！");
    }

    /**
     * 所有文件硬删除
     */
    @GetMapping("/adminDeleteHardAll/{id}")
    @Transactional
    public Result adminDeleteHardAll(@PathVariable Integer id) {
        // 查找文件记录
        //根据员工id查出所有与项目的participant表里的有自己参与的projectId(需要去重)
        Admin admin = adminMapper.selectById(id);
        if(admin == null || !admin.getStatus().equals(Admin.Status.pass)){
            return new Result(Code.DELETE_ERR, "没有删除权限");
        }
        LambdaQueryWrapper<FileEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FileEntity::getIsDelete, FileEntity.IsDelete.deleted);
        List<FileEntity> fileEntityList = fileMapper.selectList(queryWrapper);
        if(fileEntityList.size() == 0){
            return new Result(Code.DELETE_ERR, "回收站为空！");
        }
        for (FileEntity fileEntity : fileEntityList) {
            String filePath = basePath + fileEntity.getFileName();
            File file = new File(filePath);
            if (file.exists() && file.isFile()) {
                file.delete();
            }
            // 从数据库中删除文件记录
            fileMapper.deleteById(fileEntity.getId());
        }
        return new Result(Code.DELETE_OK, "回收站已清空！");
    }

    @PostMapping("/getAllTrashFiles")
    public Result getAllTrashFiles(@RequestParam("employeeId") String employeeId,
                                   @RequestBody QueryFilesCondition queryFilesCondition) {
//        System.out.println("getAllTrashFiles传的什么参数："+employeeId+queryFilesCondition);
        LambdaQueryWrapper<FileEntity> queryWrapper = new LambdaQueryWrapper<>();
        //只能看到自己(参与的项目的)软删除的
//        queryWrapper.eq(FileEntity::getEmployeeId, employeeId);
        LambdaQueryWrapper<Participant> queryWrapper1 = new LambdaQueryWrapper();
        //查出所有项目的participant表里的有自己参与的projectId(需要去重)
        queryWrapper1.select(Participant::getProjectId);
        queryWrapper1.eq(Participant::getEmployeeId, employeeId);
        queryWrapper1.groupBy(Participant::getProjectId);
        List<Participant> participantList = participantMapper.selectList(queryWrapper1);
//        System.out.println("participantList.size()是"+participantList.size());
        if(participantList.size() == 0 || participantList == null || participantList.size() == 0){
            return new Result(Code.SELECT_ERR, "没有文件，你没有参与任何项目");
        }
        List<Long> projectIds = participantList.stream().map(Participant::getProjectId).collect(Collectors.toList());
        //去掉projectIds里重复的id(没有必要？)
        projectIds = projectIds.stream().distinct().collect(Collectors.toList());
//        System.out.println("都有那些projectIds"+projectIds);
        if(projectIds == null || projectIds.size() == 0){
            return new Result(Code.SELECT_ERR, "没有文件，你没有参与任何项目");
        }
        queryWrapper.in(projectIds!=null && projectIds.size() > 0,
                FileEntity::getProjectId,projectIds);

        queryWrapper.eq(FileEntity::getIsDelete, FileEntity.IsDelete.deleted);

        //去掉数据库里文件名的---的之前的部分
        //文件名输入模糊搜索
        // 使用 apply 来添加自定义 SQL 片段
//        String sqlCondition = String.format("file_name LIKE '%%' || SUBSTR(file_name, INSTR(file_name, '---') + 2) || '%%'",
//                queryFilesCondition.getFileName());
        // 添加条件到 queryWrapper
//        queryWrapper.apply(sqlCondition);
        //搜索框1，文件名输入模糊搜索
        queryWrapper.like(!queryFilesCondition.getFileName().equals("") &&
                        queryFilesCondition.getFileName()!=null,
                FileEntity::getFileName,queryFilesCondition.getFileName());

        //搜索框2，项目名输入模糊搜索，项目删除后，文件的项目id会被清空，不能根据项目名查询了
        LambdaQueryWrapper<Project> projectQueryWrapper = new LambdaQueryWrapper();
        projectQueryWrapper.like(!queryFilesCondition.getProjectName().equals("") &&
                        queryFilesCondition.getProjectName()!=null,
                Project::getProjectName,queryFilesCondition.getProjectName());
        List<Project> projectList = projectMapper.selectList(projectQueryWrapper);
        List<Long> projectIds1 = projectList.stream().map(Project::getId).collect(Collectors.toList());
        if (projectIds1 == null || projectIds1.size() == 0) {
            queryWrapper.eq(FileEntity::getProjectId, -1);
            // 输入框输入了项目名，不能不查，但是为了防止projectIds为空时查询报错，这里设置一个不存在的id
        } else {
            queryWrapper.in(!queryFilesCondition.getProjectName().equals("") &&
                    queryFilesCondition.getProjectName()!=null,
                    FileEntity::getProjectId, projectIds1);
        }

        //搜索框3，上传人输入模糊搜索，离职后，文件的上传人id会被清空，不能根据上传人名查询了(可以初始化时查出来，只不过搜索不到罢了)
        LambdaQueryWrapper<Employee> employeeQueryWrapper = new LambdaQueryWrapper();
        employeeQueryWrapper.like(!queryFilesCondition.getEmployeeName().equals("") &&
                        queryFilesCondition.getEmployeeName()!=null,
                Employee::getName,queryFilesCondition.getEmployeeName());
        List<Employee> employeeList = employeeMapper.selectList(employeeQueryWrapper);
        List<Long> employeeIds = employeeList.stream().map(Employee::getId).collect(Collectors.toList());
        if (employeeIds == null || employeeIds.size() == 0) {
            queryWrapper.eq(FileEntity::getEmployeeId, -1);
            // 输入框输入了上传人名，不能不查，但是为了防止projectIds为空时查询报错，这里设置一个不存在的id
        } else {
            queryWrapper.in(!queryFilesCondition.getEmployeeName().equals("") &&
                            queryFilesCondition.getEmployeeName()!=null,
                    FileEntity::getEmployeeId, employeeIds);
        }

        List<FileEntity> trashFiles = fileMapper.selectList(queryWrapper);
        if (trashFiles == null) {
            return new Result(Code.SELECT_ERR, "回收站没有文件！");
        }
        List<FileEntityExt> fileEntityListExt = new ArrayList<>();
        for(FileEntity fileEntity: trashFiles){
            FileEntityExt fileEntityExt = new FileEntityExt();
            BeanUtils.copyProperties(fileEntity, fileEntityExt);
            Employee employee = null;
            if (fileEntity.getEmployeeId() != null) {
                employee = employeeService.getById(fileEntity.getEmployeeId());
                fileEntityExt.setEmployeeName(employee.getName());
            }
            Project project = null;
            if (fileEntity.getProjectId() != null) {
                project = projectMapper.selectById(fileEntity.getProjectId());
                if(project != null) {
                    fileEntityExt.setProjectName(project.getProjectName());
                }
            }
            fileEntityListExt.add(fileEntityExt);
        }

        return new Result(Code.SELECT_OK, fileEntityListExt,"查找垃圾文件成功！");
    }

    @PostMapping("/adminGetAllTrashFiles")
    public Result adminGetAllTrashFiles(@RequestBody QueryFilesCondition queryFilesCondition) {
//        System.out.println("传的什么参数："+queryFilesCondition);
        LambdaQueryWrapper<FileEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FileEntity::getIsDelete, FileEntity.IsDelete.deleted);
        //搜索框1，根据文件名模糊搜索
        queryWrapper.like(!queryFilesCondition.getFileName().equals("") &&
                        queryFilesCondition.getFileName()!=null,
                FileEntity::getFileName,queryFilesCondition.getFileName());

        //搜索框2，项目名输入模糊搜索，项目删除后，文件的项目id会被清空，不能根据项目名查询了(可以初始化时查出来，只不过搜索不到罢了)
        LambdaQueryWrapper<Project> projectQueryWrapper = new LambdaQueryWrapper();
        projectQueryWrapper.like(!queryFilesCondition.getProjectName().equals("") &&
                        queryFilesCondition.getProjectName()!=null,
                Project::getProjectName,queryFilesCondition.getProjectName());
        List<Project> projectList = projectMapper.selectList(projectQueryWrapper);
        List<Long> projectIds1 = projectList.stream().map(Project::getId).collect(Collectors.toList());
        if (projectIds1 == null || projectIds1.size() == 0) {
            queryWrapper.eq(FileEntity::getProjectId, -1);
            // 输入框输入了项目名，不能不查，但是为了防止projectIds为空时查询报错，这里设置一个不存在的id
        } else {
            queryWrapper.in(!queryFilesCondition.getProjectName().equals("") &&
                            queryFilesCondition.getProjectName()!=null,
                    FileEntity::getProjectId, projectIds1);
        }

        //搜索框3，上传人输入模糊搜索，离职后，文件的上传人id会被清空，不能根据上传人名查询了(可以初始化时查出来，只不过搜索不到罢了)
        LambdaQueryWrapper<Employee> employeeQueryWrapper = new LambdaQueryWrapper();
        employeeQueryWrapper.like(!queryFilesCondition.getEmployeeName().equals("") &&
                        queryFilesCondition.getEmployeeName()!=null,
                Employee::getName,queryFilesCondition.getEmployeeName());
        List<Employee> employeeList = employeeMapper.selectList(employeeQueryWrapper);
        List<Long> employeeIds = employeeList.stream().map(Employee::getId).collect(Collectors.toList());
        if (employeeIds == null || employeeIds.size() == 0) {
            queryWrapper.eq(FileEntity::getEmployeeId, -1);
            // 输入框输入了上传人名，不能不查，但是为了防止projectIds为空时查询报错，这里设置一个不存在的id
        } else {
            queryWrapper.in(!queryFilesCondition.getEmployeeName().equals("") &&
                            queryFilesCondition.getEmployeeName()!=null,
                    FileEntity::getEmployeeId, employeeIds);
        }

        List<FileEntity> trashFiles = fileMapper.selectList(queryWrapper);
        if (trashFiles == null) {
            return new Result(Code.SELECT_ERR, "回收站没有文件！");
        }
        List<FileEntityExt> fileEntityListExt = new ArrayList<>();
        for(FileEntity fileEntity: trashFiles){
            FileEntityExt fileEntityExt = new FileEntityExt();
            BeanUtils.copyProperties(fileEntity, fileEntityExt);
            Employee employee = null;
            if (fileEntity.getEmployeeId() != null) {
                employee = employeeService.getById(fileEntity.getEmployeeId());
                fileEntityExt.setEmployeeName(employee.getName());
            }
            Project project = null;
            if (fileEntity.getProjectId() != null) {
                project = projectMapper.selectById(fileEntity.getProjectId());
                if(project != null) {
                    fileEntityExt.setProjectName(project.getProjectName());
                }
            }
            fileEntityListExt.add(fileEntityExt);
        }
        return new Result(Code.SELECT_OK, fileEntityListExt,"查找垃圾文件成功！");
    }

}
